package org.webcat.electronicsubmissionplugin.wizard.jtree;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.JTree;
import javax.swing.text.Position.Bias;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.webcat.submitter.targets.SubmissionTarget;

/**
 * Implementation of a custom JTree to be used with SubmissionTargets.
 * @author rob44, rstodd13, samccarn
 */
public class SubmissionTargetTree extends JTree {

    /**
     * Default constructor.
     *
     */
    public SubmissionTargetTree() {
        super();
        this.setRootVisible(false);
        this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    }

    /**
     * Override convertValueToText to change the display of the objects in the tree.
     * Originally, displayed the toString of the object (in this case, a SubmissionTarget object)
     * which had no custom toString. Thus, changed the method to load the name of the SubmissionTarget.
     * No other changes made.
     * @param value the value
     * @param selected selected or not
     * @param expanded expanded or not
     * @param leaf leaf state
     * @param row the row
     * @param hasFocus focused or not
     * @return the text value to be displayed
     */
    @Override
    public String convertValueToText(Object value,
            boolean selected,
            boolean expanded,
            boolean leaf,
            int row,
            boolean hasFocus) {
        if (value instanceof SubmissionTarget) {
            SubmissionTarget obj = (SubmissionTarget) value;
            return obj.getName();
        }
        return value.toString();
    }

    /**
     * Expands all the rows (i.e, the entire tree).
     */
    public void expandAllRows() {
        for (int i = 0; i < this.getRowCount(); i++) {
            this.expandRow(i);
        }
    }

    /**
     * Expands the tree using the given path names.
     * These names correspond with the value displayed to the user on the tree.
     * @param paths the path names
     */
    public void expandForPaths(List<String> paths) {
        for (String path : paths) {
            TreePath tPath = this.getNextMatch(path, 0, Bias.Forward);
            if (tPath != null) {
                this.expandPath(tPath);
            }

        }
    }

    /**
     * Gets the names of the currently expanded paths.
     * These names correspond with the value displayed to the user on the tree.
     * @return the currently expanded paths
     */
    public List<String> getCurrentExpandedPathNames() {
        List<String> rtn = new ArrayList<String>();
        if (getModel() != null && getModel().getRoot() != null) {
            TreePath rootPath = new TreePath(this.getModel().getRoot());
            Enumeration<TreePath> expandedPaths = this.getExpandedDescendants(rootPath);
            while (expandedPaths != null && expandedPaths.hasMoreElements()) {
                TreePath path = expandedPaths.nextElement();
                if (path.getLastPathComponent() instanceof SubmissionTarget) {
                    SubmissionTarget st = (SubmissionTarget) path.getLastPathComponent();
                    rtn.add(st.getName());
                }
            }
        }
        return rtn;
    }
}
